// DBDeployer - The MySQL Sandbox
// Copyright © 2006-2020 Giuseppe Maxia
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cookbook

import (
	"fmt"
	"os"

	"github.com/datacharmer/dbdeployer/common"
)

type RecipeTemplate struct {
	Description    string
	ScriptName     string
	Notes          string
	Contents       string
	RequiredFlavor string
	IsExecutable   bool
}

type RecipesCollection map[string]RecipeTemplate

const (
	CookbookInclude       = "cookbook_include.sh"
	CookbookPrerequisites = "prerequisites.sh"
)

var recipeInclude string = `
if [ -z "$SANDBOX_HOME" ]
then
    export SANDBOX_HOME=$HOME/sandboxes
fi

if [ -z "$SANDBOX_BINARY" ]
then
    export SANDBOX_BINARY=$HOME/opt/mysql
fi

function run {
    (set -x
    $@
    )
    exit_code=$?
    echo $exit_code
    if [ "$exit_code" != "0" ]
    then
        echo "ERROR running $@"
        exit $exit_code
    fi
}

function check_version {
    wanted_version=$1
    check_upgrade=$2
    invalid_version=$(echo "$wanted_version"| grep NOTFOUND)
    if [ -z "$wanted_version" -o -n "$invalid_version" ]
    then
        echo "No version provided"
        exit 1
    fi

    if [ ! -d $SANDBOX_BINARY/$wanted_version ]
    then
        echo "Directory $SANDBOX_BINARY/$wanted_version not found"
        echo "To install the binaries, use: "
        echo "    dbdeployer unpack mysql-$version-YOUR-OPERATING-SYSTEM.tar.gz"
        exit 1
    fi
    if [ -z "$check_upgrade" ]
    then
        return
    fi
    if [ ! -x $SANDBOX_BINARY/$wanted_version/bin/mysql_upgrade ]
    then
        echo "mysql_upgrade not found in $wanted_version"
        exit 1
    fi
    version_path=$(echo msb_$wanted_version | tr '.' '_')
    if [ -d $SANDBOX_HOME/$version_path ]
    then
        echo "Version $wanted_version is already installed in $SANDBOX_HOME/$version_path"
        exit 1
    fi
}

dash_line="# ----------------------------------------------------------------------------"
star_line="# ****************************************************************************"
hash_line="# ############################################################################"

function header {
    msg="$1"
    msg2="$2"
    msg3="$3"
    echo ""
    echo "$star_line"
    echo "# $msg"
    if [ -n "$msg2" ] ; then echo "# $msg2" ; fi
    if [ -n "$msg3" ] ; then echo "# $msg3" ; fi
    echo "$star_line"
}`

var singleTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
# [ -z "$version" ] && version={{.LatestVersion}}
check_version $version


if [ -n "$(dbdeployer sandboxes | grep 'single\s*'$version)" ]
then
    echo "single version $version is already installed"
else
    header "Deploying a single sandbox for version $version"
    run dbdeployer deploy single $version
fi
`

var singleCustomUsersTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

cat << EOF > orchestrator.sql
CREATE DATABASE IF NOT EXISTS orchestrator;
CREATE USER orchestrator IDENTIFIED BY 'msandbox';
GRANT ALL PRIVILEGES ON orchestrator.* TO orchestrator;
GRANT SELECT ON mysql.slave_master_info TO orchestrator;

EOF

version=$1
[ -z "$version" ] && version=$(dbdeployer info version 8.0)
# [ -z "$version" ] && version={{.LatestVersion}}
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'custom-users.*single\s*'$version)" ]
then
    echo "single version $version with custom users is already installed"
else
    header "Deploying a single sandbox for version $version"
    run dbdeployer deploy single $version \
      --sandbox-directory=custom-users \
      --task-user=task_user \
      --custom-role-name=R_ADMIN \
      --task-user-role=R_ADMIN \
      --post-grants-sql-file=$PWD/orchestrator.sql
fi

echo ""
$HOME/sandboxes/custom-users/use -u task_user -e 'show grants\G'
echo ""
echo $dash_line
echo ""
$HOME/sandboxes/custom-users/use -u orchestrator -e 'show grants\G'
`

var adminPortTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version 8.0)
# [ -z "$version" ] && version={{.LatestVersion}}
check_version $version


header "Deploying a single sandbox for version $version"
run dbdeployer deploy single $version --enable-admin-address

sandbox_dir=msb_$(echo $version | tr '.' '_' )

header "run $SANDBOX_HOME/$sandbox_dir/use_admin" \
       "to use the database as administrator in the dedicated address" \
       "and to see the customized prompt"
`

var singleSkipStartTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'single\s*'$version)" ]
then
    echo "single version $version is already installed"
else
    header "Deploying a single sandbox for version $version without start"
    run dbdeployer deploy single $version --skip-start
fi

sandbox_dir=msb_$(echo $version | tr '.' '_' )
run $SANDBOX_HOME/$sandbox_dir/status

header "The server is deployed, but not started." \
       "Regular users have not been created" \
	   "The database is accessible by user 'root' w/o password"

header "To make the sandbox operational, you need to run" \
       "$SANDBOX_HOME/$sandbox_dir/start" \
	   "and $SANDBOX_HOME/$sandbox_dir/load_grants"
`

var singleReinstallTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -z "$(dbdeployer sandboxes | grep 'single\s*'$version)" ]
then
    echo "single version $version is not installed"
    echo "Run './single-deployment.sh $version' before trying again"
    exit 1
fi

header "Deploying the same sandbox again, with different parameters" \
       "We need to use --force, as we are overwriting an existing sandbox" \
       "Incidentally, the new deployment will run a query before and after the grants"

# run dbdeployer deploy single $version
(set -x
dbdeployer deploy single $version --pre-grants-sql='select host, user from mysql.user' \
    --post-grants-sql='select host, user from mysql.user' --force
)

sandbox_dir=msb_$(echo $version | tr '.' '_' )

header "Deploying the same sandbox with a different directory. " \
       "No --force is necessary, as dbdeployer will choose a different port"

run dbdeployer deploy single $version --sandbox-directory=${sandbox_dir}_new

echo ""
run dbdeployer sandboxes --header

header "Removing the second sandbox"
run dbdeployer delete ${sandbox_dir}_new
`

var showSandboxes string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

run dbdeployer sandboxes --full-info

# Alternative:
#
# run dbdeployer sandboxes --header --catalog
#
`
var deleteAll string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

echo "WARNING: This script deletes all installed sandboxes"

run dbdeployer delete all --concurrent

# you can also skip manual confirmation:
# run dbdeployer delete all --concurrent --skip-confirm
`

var masterSlaveDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'master-slave\s*'$version)" ]
then
    echo "replication version $version is already installed"
else
    run dbdeployer deploy replication $version --concurrent $MASTER_SLAVE_OPTIONS
fi
`

var replicationSkipStartTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

export MASTER_SLAVE_OPTIONS="--skip-start"
run ./master-slave-deployment.sh $version

sandbox_dir=rsandbox_$(echo $version | tr '.' '_' )
run $SANDBOX_HOME/$sandbox_dir/status_all

header "The servers are deployed, but not started." \
       "Regular users have not been created" \
	   "The databases are accessible by user 'root' w/o password"

header "To make the sandbox operational, you need to run" \
       "$SANDBOX_HOME/$sandbox_dir/start_all" \
	   "and $SANDBOX_HOME/$sandbox_dir/master/load_grants"

header "Note that only the master needs to load grants. The slaves get them through replication" \
       "which will start when you run $SANDBOX_HOME/$sandbox_dir/initialize_slaves"

`

var customReplicationDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'master-slave\s*'$version)" ]
then
    echo "replication version $version is already installed"
else
    header "installing a custom master/slave replication" \
           "where directories and scripts have custom names"

    run dbdeployer deploy replication $version $MASTER_SLAVE_OPTIONS \
        --defaults=master-name:primary \
        --defaults=master-abbr:p \
        --defaults=slave-prefix:replica \
        --defaults=slave-abbr:r \
        --defaults=master-slave-prefix:primary_replica_ \
        --defaults=node-prefix:branch
fi

sandbox_dir=primary_replica_$(echo $version | tr '.' '_' )
run dbdeployer sandboxes --header
run ls -l $SANDBOX_HOME/$sandbox_dir
header "Now try $SANDBOX_HOME/$sandbox_dir/p" \
       "and $SANDBOX_HOME/$sandbox_dir/check_replicas"
`

var fanInDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'fan-in\s*'$version)" ]
then
    echo "fan-in replication version $version is already installed"
else
    run dbdeployer deploy replication $version --topology=fan-in --concurrent $FAN_IN_OPTIONS
fi
`
var allMastersDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'all-masters\s*'$version)" ]
then
    echo "all-masters replication version $version is already installed"
else
    run dbdeployer deploy replication $version --topology=all-masters --concurrent $ALL_MASTERS_OPTIONS
fi
`
var groupMultiPrimaryDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'group-multi-primary\s*'$version)" ]
then
    echo "group replication version $version is already installed"
else
    run dbdeployer deploy replication $version --topology=group --concurrent $GROUP_MP_OPTIONS
fi
`
var groupSinglePrimaryDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'group-single-primary\s*'$version)" ]
then
    echo "group replication (single primary) version $version is already installed"
else
    run dbdeployer deploy replication $version --topology=group --single-primary --concurrent $GROUP_SP_OPTIONS
fi
`

var replicationRestart string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -z "$(dbdeployer sandboxes | grep 'master-slave\s*'$version)" ]
then
    echo "master-slave version $version is not installed"
    echo "Run './master-slave-deployment.sh $version' before trying again"
    exit 1
fi

sandbox_dir=$SANDBOX_HOME/rsandbox_$(echo $version | tr '.' '_' )

header "Checking the value for max-connections in all nodes"
(set -x
$sandbox_dir/use_all 'select @@max_connections'
)

header "Restarting all nodes with the new value"
(set -x
$sandbox_dir/restart_all --max-connections=66
)

header "Checking the new value for max-connections in all nodes"
(set -x
$sandbox_dir/use_all 'select @@max_connections'
)

header "Restarting slave #2 without specifying any values."
run $sandbox_dir/node2/restart

header "Checking the value for max-connections in all nodes: node #2 has again the default value"
(set -x
$sandbox_dir/use_all 'select @@max_connections'
)

header "Adding a custom number of connection permanently to slave #2 ( NOTE: no dashes! )"
(set -x
$sandbox_dir/node2/add_option max-connections=99
)

header "Restarting slave #2 without specifying any values. We'll see that its own value is preserved"
run $sandbox_dir/node2/restart

header "Checking the value for max-connections in all nodes: node #2 has kept its own value"
(set -x
$sandbox_dir/use_all 'select @@max_connections'
)
`

var replicationOperations string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version

if [ -z "$(dbdeployer sandboxes | grep 'master-slave\s*'$version)" ]
then
    echo "master-slave version $version is not installed"
    echo "Run './master-slave-deployment.sh $version' before trying again"
    exit 1
fi

sandbox_dir=$SANDBOX_HOME/rsandbox_$(echo $version | tr '.' '_' )

header "Running a simple command with the master in the sandbox." \
   "Notice the usage of the '-e', as if we were using the 'mysql' client" 

(set -x
$sandbox_dir/m -e 'SHOW MASTER STATUS'
)

header "Creating a table in the master"
(set -x
$sandbox_dir/m -e 'DROP TABLE IF EXISTS test.t1'
$sandbox_dir/m -e 'CREATE TABLE test.t1(id int not null primary key)'
)

header "Inserting 3 lines into the new table"
for N in 1 2 3
do
    (set -x
    $sandbox_dir/m -e "INSERT INTO test.t1 VALUES($N)"
    )
done
sleep 2

header "Getting the table contents from one slave"
(set -x
$sandbox_dir/s1 -e "SELECT * FROM test.t1"
)


header "Getting the table count from all nodes (NOTE: no '-e' is needed)"
(set -x
$sandbox_dir/use_all "SELECT COUNT(*) FROM test.t1"
)

header "Checking the status of all slaves"
run $sandbox_dir/check_slaves

header "Running a multiple query in all slaves"
(set -x
$sandbox_dir/use_all_slaves "STOP SLAVE; SET GLOBAL slave_parallel_workers=3; START SLAVE;show processlist "
)
`
var upgradeTemplate string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

function upgrade_db {
    UPGRADE_FROM=$1
    UPGRADE_TO=$2

    upgrade_from_dir=msb_$(echo $UPGRADE_FROM | tr '.' '_')
    upgrade_to_dir=msb_$(echo $UPGRADE_TO | tr '.' '_')

    if [ ! -d $SANDBOX_HOME/$upgrade_from_dir ]
    then
        run dbdeployer deploy single $UPGRADE_FROM --master
    fi
    if [ ! -d $SANDBOX_HOME/$upgrade_to_dir ]
    then
        run dbdeployer deploy single $UPGRADE_TO --master
    fi
    (set -x
    $SANDBOX_HOME/$upgrade_from_dir/use -e "CREATE TABLE IF NOT EXISTS test.upgrade_log(id int not null auto_increment primary key, server_id int, vers varchar(50), urole varchar(20), ts timestamp)"
    $SANDBOX_HOME/$upgrade_from_dir/use -e "INSERT INTO test.upgrade_log (server_id, vers, urole) VALUES (@@server_id, @@version, 'original')"
    verbose_allowed=$(dbdeployer admin upgrade --help| grep 'verbose\|dry-run' | wc -l | tr -d ' \t')
    upgrade_options=""
    if [ "$verbose_allowed" == "2" ]
    then
        upgrade_options="--verbose"
    fi
    dbdeployer admin upgrade $upgrade_from_dir $upgrade_to_dir $upgrade_options
    )
    if [ ! -f $upgrade_to_dir/no_upgrade ]
    then
        (set -x
        dbdeployer delete $upgrade_from_dir
        $SANDBOX_HOME/$upgrade_to_dir/use -e "INSERT INTO test.upgrade_log (server_id, vers, urole) VALUES (@@server_id, @@version, 'upgraded')"
        $SANDBOX_HOME/$upgrade_to_dir/use -e "SELECT * FROM test.upgrade_log"
        )
    fi
}

ver_55=$(dbdeployer info version 5.5)
ver_56=$(dbdeployer info version 5.6)
ver_57=$(dbdeployer info version 5.7)
ver_80=$(dbdeployer info version 8.0)

for ver in $ver_55 $ver_56 $ver_57 $ver_80
do
    check_version $ver check_upgrade
done

header "Upgrading from $ver_55 to $ver_56"
upgrade_db $ver_55 $ver_56
header "The upgraded database is now upgrading from $ver_56 to $ver_57 "
upgrade_db $ver_56 $ver_57
header "The further upgraded database is now upgrading from $ver_57 to $ver_80"
upgrade_db $ver_57 $ver_80

`
var tidbDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

tidb_version=$(dbdeployer info version --flavor=tidb)
tidb_postfix=$(echo $tidb_version | tr '.' '_')
client_version=$(dbdeployer info version 5.7)
single_path=msb_$tidb_postfix
multiple_path=multi_msb_$tidb_postfix
if [ ! -d $SANDBOX_BINARY/$tidb_version ]
then
    echo "Get tidb from one of these URLs" 
    echo "wget https://download.pingcap.org/tidb-master-darwin-amd64.tar.gz"
    echo "wget https://download.pingcap.org/tidb-master-linux-amd64.tar.gz"
    exit 1
fi

if [ ! -d $SANDBOX_BINARY/$client_version ]
then
    echo "You need MySQL $client_version unpacked in $SANDBOX_BINARY" 
    exit 1
fi

deploy_single=yes
deploy_multi=yes
if [ -d $SANDBOX_HOME/$single_path ]
then
    echo "single TiDB already installed in $SANDBOX_HOME/$single_path"
    deploy_single=
fi

if [ -d $SANDBOX_HOME/$multiple_path ]
then
    echo "multiple TiDB already installed in $SANDBOX_HOME/$multiple_path"
    deploy_multi=
fi

if [ "$deploy_single" == "yes" ]
then
    dbdeployer deploy single $tidb_version --client-from=$client_version $TIDB_SINGLE_OPTIONS
fi

if [ "$deploy_multi" == "yes" ]
then
    dbdeployer deploy multiple $tidb_version --client-from=$client_version $TIDB_MULTI_OPTIONS
fi

$SANDBOX_HOME/$single_path/test_sb
$SANDBOX_HOME/$multiple_path/test_sb_all
`
var remoteOperations string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

run dbdeployer downloads list

version=$1
if [ -z "$version" ] 
then
    echo ""
	echo "Syntax $0 version"
	exit 1
fi

newest=$(dbdeployer downloads get-by-version $version --newest --dry-run | grep 'Name:' | awk '{print $2}')
run dbdeployer downloads get-by-version $version --newest
if [ ! -f $newest ]
then
	echo "error downloading $newest"
	exit 1
fi

dbdeployer unpack ./$newest
`

var ndbDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
recipes_dir=$(dirname $0)
cd $recipes_dir
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version --flavor=ndb)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'ndb\s*'$version)" ]
then
    echo "ndb replication version $version is already installed"
else
    
    run dbdeployer deploy replication $version --topology=ndb --concurrent $NDB_OPTIONS
fi
`
var pxcDeployment string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
recipes_dir=$(dirname $0)
cd $recipes_dir
source cookbook_include.sh

os=$(uname -s | tr 'A-Z' 'a-z')
if [ "$os" != "linux" ]
then
    echo "PXC topology is only available on Linux"
    exit 1
fi

version=$1
[ -z "$version" ] && version=$(dbdeployer info version --flavor=pxc)
check_version $version

if [ -n "$(dbdeployer sandboxes | grep 'pxc\s*'$version)" ]
then
    echo "pxc replication version $version is already installed"
else
    run dbdeployer deploy replication $version --topology=pxc --concurrent $PXC_OPTIONS
fi
`

var prerequisites string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
os=$(uname -s | tr 'A-Z' 'a-z')

if [ -z "$HOME" ]
then
    echo "Environment variable \$HOME not set"
    echo "nothing will work until this variable is defined"
    exit 1
fi

if [ -d $SANDBOX_BINARY ]
then
    echo "\$SANDBOX_BINARY directory '$SANDBOX_BINARY' exists"
else
    header "Creating Sandbox binary directory ($SANDBOX_BINARY)"
    mkdir -p $SANDBOX_BINARY	
fi

found_versions=$(ls $SANDBOX_BINARY | wc -l | tr -d '\t ' )

function get_prerequisites_linux {
    echo "# FOR REGULAR MYSQL"
    echo "# run the commands: "
    echo ""
    echo "1. dbdeployer downloads list"
    echo "2. dbdeployer downloads get-by-version 5.7 --newest --minimal"
    echo "3. dbdeployer unpack mysql-5.7.26.tar.xz"
    echo ""
    echo "4. dbdeployer versions"
    echo ""
    echo "# FOR MySQL forks, MySQL Cluster, PXC:"
    echo ""
    echo "# 1. Get the binaries from the maker download pages"
    echo "# 2. run the command"
    echo " dbdeployer unpack FlavorName-X.X.XX-OS.tar.gz  --prefix=FlavorName"
    echo "3. dbdeployer versions"
}

function get_prerequisites_darwin {
    echo "# 1a. Get the binaries from https://dev.mysql.com/downloads"
	echo "  dbdeployer downloads get mysql-5.7.26-macos10.14-x86_64.tar.gz "
	echo "  dbdeployer downloads get mysql-8.0.16-macos10.14-x86_64.tar.gz "
	echo "  dbdeployer downloads get-by-version 8.0 --newest"
    echo "# or"
    echo "# 1b. Get the binaries from the MySQL fork download pages"
    echo "# run the commands:"
    echo "2a. dbdeployer unpack mysql-5.7.26-macos10.14-x86_64.tar.gz [--prefix=FlavorName]"
	echo "# or"
    echo "2b. dbdeployer unpack mysql-8.0.16-macos10.14-x86-64bit.tar.gz [--prefix=FlavorName]"
	echo "# or"
    echo "2c. dbdeployer unpack FlavorName-X.X.XX-OS.tar.gz  --prefix=FlavorName"
    echo "3. dbdeployer versions"
}

more_opts=""
if [ $found_versions != 0 ]
then
    echo "# Found versions ready to use:"
    dbdeployer versions
    echo ""
    more_opts="[MORE]"
fi

echo ""
echo "## HOW TO GET $more_opts binaries for dbdeployer "
case $os in 
linux)
    get_prerequisites_linux
    ;;
darwin)
    get_prerequisites_darwin
    ;;
*)
    echo "operating system $os not supported"
    exit 1
    ;;
esac

`

var replicationBetweenGroups string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}

cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

group1=group_${path_version}_1
group2=group_${path_version}_2

run dbdeployer deploy replication $version --topology=group --concurrent \
        --port-as-server-id --sandbox-directory=$group1

run dbdeployer deploy replication $version --topology=group --concurrent \
        --port-as-server-id --sandbox-directory=$group2

run dbdeployer sandboxes --full-info

run $SANDBOX_HOME/$group1/replicate_from $group2

echo "# Inserting data in $group2 node1"
(set -x
$SANDBOX_HOME/$group2/n1 -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$group2/n1 -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from one of $group1 nodes"
echo "# At this point, the data was replicated twice"
(set -x
$SANDBOX_HOME/$group1/n2 -e 'select *, @@port from test.t1'
)
`
var replicationBetweenMasterSlave string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

master_slave1=ms_${path_version}_1
master_slave2=ms_${path_version}_2

run dbdeployer deploy replication $version --topology=master-slave --concurrent \
    --port-as-server-id --sandbox-directory=$master_slave1 \
    -c log-slave-updates

	run dbdeployer deploy replication $version --topology=master-slave --concurrent \
    --port-as-server-id --sandbox-directory=$master_slave2 \
    -c log-slave-updates

run dbdeployer sandboxes --full-info

gtid_executed=$($SANDBOX_HOME/$master_slave2/m -BN -e 'select @@global.gtid_executed')
$SANDBOX_HOME/$master_slave1/m -e "set global gtid_purged='$gtid_executed'"

run $SANDBOX_HOME/$master_slave1/replicate_from $master_slave2

echo "# Inserting data in $master_slave2 master"
(set -x
$SANDBOX_HOME/$master_slave2/m -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$master_slave2/m -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from $master_slave1 slave"
echo "# At this point, the data was replicated twice"
(set -x
$SANDBOX_HOME/$master_slave1/s1 -e 'select *, @@port from test.t1'
)
`

var replicationBetweenNdb string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version --flavor=ndb)
check_version $version
path_version=$(echo $version | tr '.' '_')

alpha=alpha_${path_version}
bravo=bravo_${path_version}

run dbdeployer deploy replication $version --topology=ndb  \
        --port-as-server-id --sandbox-directory=$alpha \
        -c ndb-log-bin \
        --concurrent

run dbdeployer deploy replication $version --topology=ndb  \
        --port-as-server-id --sandbox-directory=$bravo \
        -c ndb-log-bin \
        --concurrent

run dbdeployer sandboxes --full-info

run $SANDBOX_HOME/$bravo/replicate_from $alpha

echo "# Inserting data in $alpha node1"
(set -x
$SANDBOX_HOME/$alpha/n1 -e 'create schema if not exists new_db'
$SANDBOX_HOME/$alpha/n1 -e 'create table if not exists new_db.ndbt1 (id int not null primary key, server_id int ) engine=ndbcluster'
$SANDBOX_HOME/$alpha/n1 -e 'insert into new_db.ndbt1 values (1, @@server_id)'
)

sleep 3
echo "# Retrieving data from one of $bravo nodes"
echo "# At this point, the data was replicated twice"
(set -x
$SANDBOX_HOME/$bravo/n2 -e 'select *, @@port from new_db.ndbt1'
)
$SANDBOX_HOME/$alpha/use_all 'show tables from new_db'
$SANDBOX_HOME/$bravo/use_all 'show tables from new_db'
`

var replicationBetweenDiffVersions string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

ver_master=$1
ver_slave1=$2
ver_slave2=$3

[ -z "$ver_master" ] && ver_master=$(dbdeployer info version 5.6)
[ -z "$ver_slave1" ] && ver_slave1=$(dbdeployer info version 5.7)
[ -z "$ver_slave2" ] && ver_slave2=$(dbdeployer info version 8.0)

for ver in $ver_master $ver_slave1 $ver_slave2
do
    check_version $ver
done

master_path=mv_master
slave1_path=mv_slave1
slave2_path=mv_slave2

header "Installing $ver_master"
run dbdeployer deploy single $ver_master --master --sandbox-directory=$master_path
header "Installing $ver_slave1"
run dbdeployer deploy single $ver_slave1 --master --sandbox-directory=$slave1_path
header "Installing $ver_slave2"
run dbdeployer deploy single $ver_slave2 --master --sandbox-directory=$slave2_path

header "Starting replication from $master_path to $slave2_path"
run $SANDBOX_HOME/$slave2_path/replicate_from $master_path
header "Starting replication from $master_path to $slave1_path"
run $SANDBOX_HOME/$slave1_path/replicate_from $master_path

header "Generating data in $master_path"

(set -x
$SANDBOX_HOME/$master_path/use -e "create table if not exists test.t1(id int not null primary key, p int, s int, v varchar(50))"
$SANDBOX_HOME/$master_path/use -e "insert into test.t1 values (1, @@port, @@server_id, @@version)"
)

sleep 1
header "Retrieving data from $slave2_path"
(set -x
$SANDBOX_HOME/$slave2_path/use -e "select p as master_port, s as master_server_id, v as master_version, @@port, @@server_id, @@version from test.t1"
)

header "Retrieving data from $slave1_path"
(set -x
$SANDBOX_HOME/$slave1_path/use -e "select p as master_port, s as master_server_id, v as master_version, @@port, @@server_id, @@version from test.t1"
)
`

var replicationBetweenSingle string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

single1=msb_${path_version}_1
single2=msb_${path_version}_2

run dbdeployer deploy single $version --master --gtid \
        --sandbox-directory=$single1 --port-as-server-id

run dbdeployer deploy single $version --master --gtid \
        --sandbox-directory=$single2 --port-as-server-id

run dbdeployer sandboxes --full-info

gtid_executed=$($SANDBOX_HOME/$single2/use -BN -e 'select @@global.gtid_executed')
$SANDBOX_HOME/$single1/use -e "set global gtid_purged='$gtid_executed'"

run $SANDBOX_HOME/$single1/replicate_from $single2

echo "# Inserting data in $single2 "
(set -x
$SANDBOX_HOME/$single2/use -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$single2/use -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from $single1 "
(set -x
$SANDBOX_HOME/$single1/use -e 'select *, @@port from test.t1'
)`

var circularReplication string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

multi=multi_msb_${path_version}

run dbdeployer deploy multiple $version \
        --sandbox-directory=$multi \
        -c auto-increment-increment=3 \
        -c auto-increment-offset=10 \
        -c log-slave-updates \
        --concurrent

run dbdeployer sandboxes --full-info

run $SANDBOX_HOME/$multi/node1/replicate_from $multi/node3
run $SANDBOX_HOME/$multi/node2/replicate_from $multi/node1
run $SANDBOX_HOME/$multi/node3/replicate_from $multi/node2

for N in 1 2 3
do
    echo "# Creating a table in node$N "
    (set -x
    $SANDBOX_HOME/$multi/n$N -e "create table if not exists test.t$N (id int not null auto_increment primary key, node int )"
    $SANDBOX_HOME/$multi/n$N -e "insert into test.t$N values (NULL, $N)"
    )
done

for N in 1 2 3
do
    echo "# Inserting more data in node$N "
    # Inserting data in every table from every node
	for J in 1 2 3
	do
        (set -x
        $SANDBOX_HOME/$multi/n$N -e "insert into test.t$J values (NULL, $N)"
        )
	done
done

sleep 1

echo "# Retrieving data from every node "
export MYCLIENT_OPTIONS=-t
(set -x
$SANDBOX_HOME/$multi/use_all "select *, @@server_id from test.t1; select *, @@server_id from test.t2 ;select *, @@server_id from test.t3"
)
`

var replicationSingleGroup string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

group=group_msb_${path_version}
single=msb_${path_version}

run dbdeployer deploy replication $version --topology=group --concurrent \
        --port-as-server-id --sandbox-directory=$group

run dbdeployer deploy single $version --master \
        --sandbox-directory=$single

run dbdeployer sandboxes --full-info
(set -x
$SANDBOX_HOME/$single/use -e 'set global enforce_gtid_consistency=on'
$SANDBOX_HOME/$single/use -e 'set global gtid_mode=off_permissive'
$SANDBOX_HOME/$single/use -e 'set global gtid_mode=on_permissive'
$SANDBOX_HOME/$single/use -e 'set global gtid_mode=on'
)

run $SANDBOX_HOME/$group/replicate_from $single

echo "# Inserting data in $single "
(set -x
$SANDBOX_HOME/$single/use -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$single/use -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from one of $group nodes"
echo "# At this point, the data was replicated twice"
(set -x
$SANDBOX_HOME/$group/n2 -e 'select *, @@port from test.t1'
)`

var replicationGroupSingle string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

group=group_msb_${path_version}
single=msb_${path_version}

run dbdeployer deploy replication $version --topology=group --concurrent \
        --port-as-server-id --sandbox-directory=$group

run dbdeployer deploy single $version --master --gtid \
        --sandbox-directory=$single

run dbdeployer sandboxes --full-info

run $SANDBOX_HOME/$single/replicate_from $group

echo "# Inserting data in $group node1 "
(set -x
$SANDBOX_HOME/$group/n1 -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$group/n1 -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from $single "
(set -x
$SANDBOX_HOME/$single/use -e 'select *, @@port from test.t1'
)`

var replicationGroupMasterSlave string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')
group=group_msb_${path_version}
ms=rsandbox_${path_version}

run dbdeployer deploy replication $version --topology=group \
    --concurrent \
    --port-as-server-id \
    --sandbox-directory=$group

run dbdeployer deploy replication $version --topology=master-slave \
    --concurrent \
    --gtid \
    --sandbox-directory=$ms \
    --port-as-server-id \
    -c log-slave-updates

run dbdeployer sandboxes --full-info

run $SANDBOX_HOME/$ms/replicate_from $group

echo "# Inserting data in $group node1 "
(set -x
$SANDBOX_HOME/$group/n1 -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$group/n1 -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from $ms first slave"
(set -x
$SANDBOX_HOME/$ms/s1 -e 'select *, @@port from test.t1'
)
`

var replicationMasterSlaveGroup string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh

version=$1
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')

group=group_msb_${path_version}
ms=rsandbox_${path_version}

run dbdeployer deploy replication $version --topology=group \
    --concurrent \
    --port-as-server-id \
    --sandbox-directory=$group

run dbdeployer deploy replication $version --topology=master-slave \
    --concurrent \
    --sandbox-directory=$ms \
    --port-as-server-id \
    -c log-slave-updates

run dbdeployer sandboxes --full-info

sleep 3
(set -x
$SANDBOX_HOME/$ms/use_all_slaves 'stop slave'
$SANDBOX_HOME/$ms/use_all 'set global enforce_gtid_consistency=on'
$SANDBOX_HOME/$ms/use_all 'set global gtid_mode=off_permissive'
sleep 1
$SANDBOX_HOME/$ms/use_all 'set global gtid_mode=on_permissive'
sleep 1
$SANDBOX_HOME/$ms/use_all 'set global gtid_mode=on'
sleep 1
$SANDBOX_HOME/$ms/use_all_slaves 'start slave'
)

run $SANDBOX_HOME/$group/replicate_from $ms

echo "# Inserting data in $ms master "
(set -x
$SANDBOX_HOME/$ms/m -e 'create table if not exists test.t1 (id int not null primary key, server_id int )'
$SANDBOX_HOME/$ms/m -e 'insert into test.t1 values (1, @@server_id)'
)

sleep 1
echo "# Retrieving data from $group second node "
(set -x
$SANDBOX_HOME/$group/n2 -e 'select *, @@port from test.t1'
)
`

/*
var newName string = `#!{{.ShellPath}}
{{.Copyright}}
# Generated by dbdeployer {{.AppVersion}} using template {{.TemplateName}} on {{.DateTime}}
cd $(dirname $0)
source cookbook_include.sh
[ -z "$version" ] && version=$(dbdeployer info version)
check_version $version
path_version=$(echo $version | tr '.' '_')
`
*/

var RecipesList = RecipesCollection{
	"include": RecipeTemplate{
		ScriptName:  CookbookInclude,
		Description: "common code for all recipes",
		Contents:    recipeInclude,
	},
	"single": RecipeTemplate{
		Description:  "Creation of a single sandbox",
		ScriptName:   "single-deployment.sh",
		Contents:     singleTemplate,
		IsExecutable: true,
	},
	"skip-start-single": RecipeTemplate{
		Description:  "Single sandbox deployed without starting the server",
		ScriptName:   "skip-start-single.sh",
		Contents:     singleSkipStartTemplate,
		IsExecutable: true,
	},
	"skip-start-replication": RecipeTemplate{
		Description:  "Replication sandbox deployed without starting the servers",
		ScriptName:   "skip-start-replication.sh",
		Contents:     replicationSkipStartTemplate,
		IsExecutable: true,
	},
	"custom-named-replication": RecipeTemplate{
		Description:  "Replication sandbox with custom names for directories and scripts",
		ScriptName:   "custom-named-replication.sh",
		Contents:     customReplicationDeployment,
		IsExecutable: true,
	},
	"custom-users": RecipeTemplate{
		Description:    "Single sandbox with custom users",
		ScriptName:     "single-custom-users.sh",
		Contents:       singleCustomUsersTemplate,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"admin": RecipeTemplate{
		Description:    "Single sandbox with admin address enabled",
		ScriptName:     "admin-single.sh",
		Contents:       adminPortTemplate,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"single-reinstall": RecipeTemplate{
		Description:  "Re-installs a single sandbox",
		ScriptName:   "single-reinstall.sh",
		Contents:     singleReinstallTemplate,
		IsExecutable: true,
	},
	"show": RecipeTemplate{
		Description:  "Show deployed sandboxes",
		ScriptName:   "show-sandboxes.sh",
		Contents:     showSandboxes,
		IsExecutable: true,
	},
	"delete": RecipeTemplate{
		Description:  "Delete all deployed sandboxes",
		ScriptName:   "delete-sandboxes.sh",
		Contents:     deleteAll,
		IsExecutable: true,
	},
	"master-slave": RecipeTemplate{
		Description:  "Creation of a master/slave replication sandbox",
		ScriptName:   "master-slave-deployment.sh",
		Contents:     masterSlaveDeployment,
		IsExecutable: true,
	},
	"fan-in": RecipeTemplate{
		Description:    "Creation of a fan-in (many masters, one slave) replication sandbox",
		ScriptName:     "fan-in-deployment.sh",
		Contents:       fanInDeployment,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"all-masters": RecipeTemplate{
		Description:    "Creation of an all-masters replication sandbox",
		ScriptName:     "all-masters-deployment.sh",
		Contents:       allMastersDeployment,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"group-multi": RecipeTemplate{
		Description:    "Creation of a multi-primary group replication sandbox",
		ScriptName:     "group-multi-primary-deployment.sh",
		Contents:       groupMultiPrimaryDeployment,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"group-single": RecipeTemplate{
		Description:    "Creation of a single-primary group replication sandbox",
		ScriptName:     "group-single-primary-deployment.sh",
		Contents:       groupSinglePrimaryDeployment,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"replication-restart": RecipeTemplate{
		Description:  "Show how to restart sandboxes with custom options",
		ScriptName:   "repl-operations-restart.sh",
		Contents:     replicationRestart,
		IsExecutable: true,
	},
	"replication-operations": RecipeTemplate{
		Description:  "Show how to run operations in a replication sandbox",
		ScriptName:   "repl-operations.sh",
		Contents:     replicationOperations,
		IsExecutable: true,
	},
	"upgrade": RecipeTemplate{
		Description:    "Shows a complete upgrade example from 5.5 to 8.0",
		ScriptName:     "upgrade.sh",
		Contents:       upgradeTemplate,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"tidb": RecipeTemplate{
		Description:    "Shows deployment and some operations with TiDB",
		ScriptName:     "tidb-deployment.sh",
		Contents:       tidbDeployment,
		RequiredFlavor: common.TiDbFlavor,
		IsExecutable:   true,
	},
	"ndb": RecipeTemplate{
		Description:    "Shows deployment with ndb",
		ScriptName:     "ndb-deployment.sh",
		Contents:       ndbDeployment,
		RequiredFlavor: common.NdbFlavor,
		IsExecutable:   true,
	},
	"pxc": RecipeTemplate{
		Description:    "Shows deployment with pxc",
		ScriptName:     "pxc-deployment.sh",
		Contents:       pxcDeployment,
		RequiredFlavor: common.PxcFlavor,
		IsExecutable:   true,
	},
	"remote": RecipeTemplate{
		Description:  "Shows how to get a remote MySQL tarball",
		ScriptName:   "remote.sh",
		Contents:     remoteOperations,
		IsExecutable: true,
	},
	"prerequisites": RecipeTemplate{
		Description:  "Shows dbdeployer prerequisites and how to make them",
		ScriptName:   CookbookPrerequisites,
		Contents:     prerequisites,
		IsExecutable: true,
	},
	"replication_between_groups": RecipeTemplate{
		Description:    "Shows how to run replication between two group replications",
		ScriptName:     "replication-between-groups.sh",
		Contents:       replicationBetweenGroups,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"replication_between_master_slave": RecipeTemplate{
		Description:  "Shows how to run replication between two master/slave replications",
		ScriptName:   "replication-between-master-slave.sh",
		Contents:     replicationBetweenMasterSlave,
		IsExecutable: true,
	},
	"replication_between_ndb": RecipeTemplate{
		Description:    "Shows how to run replication between two NDB clusters",
		ScriptName:     "replication-between-ndb.sh",
		Contents:       replicationBetweenNdb,
		RequiredFlavor: common.NdbFlavor,
		IsExecutable:   true,
	},
	"replication_multi_versions": RecipeTemplate{
		Description:  "Shows how to run replication between different MySQL versions",
		ScriptName:   "replication-multi-versions.sh",
		Contents:     replicationBetweenDiffVersions,
		IsExecutable: true,
	},
	"replication_group_single": RecipeTemplate{
		Description:    "Shows how to run replication between a group replication and a single sandbox",
		ScriptName:     "replication-group-single.sh",
		Contents:       replicationGroupSingle,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"replication_single_group": RecipeTemplate{
		Description:    "Shows how to run replication between a single sandbox an group replication",
		ScriptName:     "replication-single-group.sh",
		Contents:       replicationSingleGroup,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"replication_between_single": RecipeTemplate{
		Description:  "Shows how to run replication between two single sandboxes",
		ScriptName:   "replication-between-single.sh",
		Contents:     replicationBetweenSingle,
		IsExecutable: true,
	},
	"circular_replication": RecipeTemplate{
		Description:  "Shows how to run replication between nodes of a multiple deployment",
		ScriptName:   "circular-replication.sh",
		Contents:     circularReplication,
		IsExecutable: true,
	},
	"replication_group_master_slave": RecipeTemplate{
		Description:    "Shows how to run replication between a group replication and master/slave replication",
		ScriptName:     "replication-group-master-slave.sh",
		Contents:       replicationGroupMasterSlave,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
	"replication_master_slave_group": RecipeTemplate{
		Description:    "Shows how to run replication between master/slave replication and group replication",
		ScriptName:     "replication-master-slave-group.sh",
		Contents:       replicationMasterSlaveGroup,
		RequiredFlavor: common.MySQLFlavor,
		IsExecutable:   true,
	},
}

func init() {
	var seen = make(map[string]bool)
	for name, recipe := range RecipesList {
		_, found := seen[recipe.ScriptName]
		if found {
			// script name already exists:
			fmt.Printf("Duplicate script name %s found in %s\n", recipe.ScriptName, name)
			os.Exit(1)

		}
	}
}
